package com.org.cn.dao.base;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.org.cn.bean.base.QueryResult;
import com.org.cn.uitls.base.GenericsUtils;

/**
 * 
 * 
 * @Description: DAO层封装使用了泛型，包含常用的CURD和分页操作
 * 
 * @author Grandzu
 * 
 * @create_time Jun 14, 2013 2:13:45 PM
 * 
 * @version
 * 
 * @param <T>
 */
@SuppressWarnings("unchecked")
public abstract class BaseDaoSupport<T> extends HibernateDaoSupport implements
		IBaseDao<T> {

	protected Class<T> entityClass = GenericsUtils.getSuperClassGenricType(this
			.getClass());
	protected String entityClassName = getEntityName(this.entityClass);

	
	public List<T> findByEntity(Object entiey) {
		return super.getHibernateTemplate().findByExample(entiey);
	}

	
	public List<T> findByProperty(String propertyName, Object value) {
		String queryString = "from " + entityClassName + " o where o."
				+ propertyName + "= ?";
		return super.getHibernateTemplate().find(queryString, value);
	}

	
	public void delete(Serializable... entityids) {
		for (Object id : entityids) {
			super.getHibernateTemplate().delete(find((Serializable) id));
		}
	}

	
	public T find(Serializable entityId) {
		if (null != entityId)
			return (T) super.getHibernateTemplate().get(entityClass, entityId);
		return null;
	}

	public void save(Object entity) {
		super.getHibernateTemplate().save(entity);
	}

	
	public void update(Object entity) {
		super.getHibernateTemplate().update(entity);
	}

	public QueryResult<T> getScrollData(final int firstindex,
			final int maxresult, final String wherejpql,
			final Object[] queryParams,
			final LinkedHashMap<String, String> orderby) {
		final QueryResult<T> queryResult = new QueryResult<T>();

		super.getHibernateTemplate().execute(new HibernateCallback<T>() {
			public T doInHibernate(Session session) throws HibernateException,
					SQLException {
				String hql = "from "
						+ entityClassName
						+ " o "
						+ (wherejpql == null || "".equals(wherejpql.trim()) ? ""
								: " where " + wherejpql)
						+ buildOrderby(orderby);
				Query query = session.createQuery(hql);
				setQueryParams(query, queryParams);// where
				queryResult.setTotalRecord(query.list().size());// first get
				// size

				if (firstindex != -1 && maxresult != -1)
					query.setFirstResult(firstindex).setMaxResults(maxresult);// last
				// page

				queryResult.setResultList(query.list());

				return null;
			}

		});

		return queryResult;

	}

	
	public QueryResult<T> getScrollData(int firstindex, int maxresult,
			String wherejpql, Object[] queryParams) {
		return getScrollData(firstindex, maxresult, wherejpql, queryParams,
				null);
	}

	
	public QueryResult<T> getScrollData(final int firstindex,
			final int maxresult, final LinkedHashMap<String, String> orderby) {
		return getScrollData(firstindex, maxresult, null, null, orderby);

	}

	public QueryResult<T> getScrollData(final int firstindex,
			final int maxresult) {
		return getScrollData(firstindex, maxresult, null, null, null);
	}

	public QueryResult<T> getScrollData() {
		return getScrollData(-1, -1, null, null, null);
	}


	/**
	 * 获取实体的名称
	 * 
	 * @param <E>
	 * @param clazz
	 *            实体类
	 * @return
	 */
	protected static <E> String getEntityName(Class<E> clazz) {
		String entityname = clazz.getSimpleName();
		return entityname;
	}

	/**
	 * 设置HQL里边的属性值
	 * 
	 * @param query
	 * @param queryParams
	 */
	protected static void setQueryParams(Query query, Object[] queryParams) {
		if (queryParams != null && queryParams.length > 0) {
			for (int i = 0; i < queryParams.length; i++) {
				query.setParameter(i, queryParams[i]);// 从0开始
			}
		}
	}

	/**
	 * 组装order by语句
	 * 
	 * @param orderby
	 * @return
	 */
	protected static String buildOrderby(LinkedHashMap<String, String> orderby) {
		StringBuffer orderbyql = new StringBuffer("");
		if (orderby != null && orderby.size() > 0) {
			orderbyql.append(" order by ");
			for (String key : orderby.keySet()) {
				orderbyql.append("o.").append(key).append(" ").append(
						orderby.get(key)).append(",");
			}
			orderbyql.deleteCharAt(orderbyql.length() - 1);
		}
		return orderbyql.toString();
	}
}
